"""
MySQL数据库连接模块，用于连接MySQL数据库
"""
import pymysql
from typing import List, Dict, Any, Optional
import time # Added for retry mechanism

from src.utils.config import config_manager
from src.utils.logger import logger


class MySQLManager:
    """MySQL管理类，用于连接MySQL数据库"""
    
    def __init__(self):
        """初始化MySQL管理器"""
        self.conn = None
        self.config = config_manager.get_database_config()
    
    def _reload_config(self):
        """重新加载数据库配置"""
        # 重新加载配置文件
        config_manager.load()
        # 更新数据库配置
        self.config = config_manager.get_database_config()
        logger.debug(f"已重新加载数据库配置: {self.config['host']}:{self.config['port']}")
    
    def connect(self) -> bool:
        """
        连接数据库
        
        Returns:
            bool: 是否成功连接
        """
        try:
            # 每次连接前重新加载配置
            self._reload_config()
            
            # 如果已连接，检查连接是否有效
            if self.conn:
                try:
                    self.conn.ping(reconnect=True)
                    logger.debug("数据库连接有效")
                    return True
                except Exception as ping_error:
                    logger.debug(f"数据库连接已失效: {ping_error}")
                    # 连接已失效，关闭连接
                    try:
                        self.conn.close()
                    except:
                        pass
                    self.conn = None
            
            # 创建新连接，添加连接超时和重试机制
            max_retries = 3
            retry_count = 0
            
            while retry_count < max_retries:
                try:
                    logger.debug(f"尝试连接数据库: {self.config['host']}:{self.config['port']}, 第{retry_count + 1}次尝试")
                    self.conn = pymysql.connect(
                        host=self.config["host"],
                        port=int(self.config["port"]),
                        user=self.config["user"],
                        password=self.config["password"],
                        database=self.config["database"],
                        charset=self.config["charset"],
                        cursorclass=pymysql.cursors.DictCursor,
                        connect_timeout=10,  # 设置连接超时时间为10秒
                        read_timeout=30,     # 读取超时时间30秒
                        write_timeout=30     # 写入超时时间30秒
                    )
                    
                    logger.info(f"数据库连接成功: {self.config['host']}:{self.config['port']}")
                    return True
                except pymysql.err.OperationalError as e:
                    # 特殊处理"too many connections"错误
                    if e.args[0] == 1040:  # 1040是MySQL的"too many connections"错误码
                        logger.warning(f"数据库连接数已达到最大值，等待5秒后重试: {e}")
                        time.sleep(5)  # 等待5秒后重试
                    else:
                        logger.error(f"数据库连接操作异常: {e}，等待2秒后重试")
                        time.sleep(2)
                    
                    retry_count += 1
                except Exception as e:
                    logger.error(f"数据库连接异常: {e}，等待2秒后重试")
                    time.sleep(2)
                    retry_count += 1
            
            logger.error(f"数据库连接失败，已达到最大重试次数: {max_retries}")
            return False
        except Exception as e:
            logger.error(f"数据库连接异常: {e}")
            return False
    
    def close(self) -> bool:
        """
        关闭数据库连接
        
        Returns:
            bool: 是否成功关闭
        """
        try:
            if self.conn:
                self.conn.close()
                self.conn = None
                logger.debug("数据库连接已关闭")
            return True
        except Exception as e:
            logger.error(f"关闭数据库连接异常: {e}")
            return False
    
    def query(self, sql: str, params: Optional[Any] = None) -> List[Dict[str, Any]]:
        """
        执行查询操作
        
        Args:
            sql: SQL语句
            params: 参数
        
        Returns:
            List[Dict[str, Any]]: 查询结果
        """
        try:
            # 确保连接有效
            if not self.connect():
                logger.error("数据库连接失败，无法执行查询")
                return []

            # 执行查询
            with self.conn.cursor() as cursor:
                cursor.execute(sql, params)
                results = cursor.fetchall()
            
            logger.debug(f"查询成功: {sql[:100]}{'...' if len(sql) > 100 else ''}")
            return list(results)
        except Exception as e:
            logger.error(f"查询异常: {e}")
            # 尝试重新连接
            self.close()
            if self.connect():
                try:
                    with self.conn.cursor() as cursor:
                        cursor.execute(sql, params)
                        results = cursor.fetchall()
                    logger.info("查询重试成功")
                    return list(results)
                except Exception as retry_error:
                    logger.error(f"查询重试异常: {retry_error}")
            return []
    
    def execute(self, sql: str, params: Optional[Any] = None) -> int:
        """
        执行增删改操作
        
        Args:
            sql: SQL语句
            params: 参数
        
        Returns:
            int: 影响行数
        """
        try:
            # 确保连接有效（会自动重新加载配置）
            if not self.connect():
                logger.error("数据库连接失败，无法执行操作")
                return 0
            
            # 执行操作
            with self.conn.cursor() as cursor:
                rows = cursor.execute(sql, params)
                self.conn.commit()
            
            logger.debug(f"执行成功: {sql[:100]}{'...' if len(sql) > 100 else ''}, 影响行数: {rows}")
            return rows
        except Exception as e:
            logger.error(f"执行异常: {e}")
            if self.conn:
                try:
                    self.conn.rollback()
                except:
                    pass
            return 0


# 创建全局MySQL管理器实例
mysql_manager = MySQLManager() 